package com.xs.controller;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xs.dto.UserAddress;
import com.xs.dto.UserAddressDto;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import com.xs.service.UserService;
import com.xs.utils.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@RestController// 1、控制器
@RequestMapping("user") // 2、请求映射：用在类上表示是一级路径
public class UserController {

    @Autowired// 3、自动接线---业务层
    private UserService userService;

    // 3.1 添加---用于接收上路径
    String userImagePath = null;

    @RequestMapping("findAll") // 4、请求映射：用在方法上表示是二级路径
    public List<User> fidAll() { // 5、查询所有方法
        return userService.findAll();
    }

    /**
     * 1、分页
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @RequestMapping("findByPage")
    public JsonResult<User> findByPage(
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(value = "limit", required = false, defaultValue = "3") Integer pageSize
    ) {

        // 设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        // 只对紧跟startPage后面的方法才会进行分页
        List<User> userList = userService.findAll();
        // 封装到PageInfo对象中
        PageInfo<User> userPageInfo = new PageInfo<>(userList);
        // 判断
        if (userList != null) {
            // 返回分页数据
            JsonResult jsonResult = JsonResult.ok();
            // 返回分页数据
            jsonResult.setData(userPageInfo.getList());
            // 返回总记录数
            jsonResult.setCount(userPageInfo.getTotal());

            return jsonResult;
        }

        return JsonResult.error();
    }

    /**
     * 2、layUI上传封装对象的名称使用file
     */
    @RequestMapping("upload")
    public JsonResult upload(MultipartFile file) {

        // 2.1 获取上传路径
        String uploadPath = "D:\\tomcat-two\\apache-tomcat-9.0.33\\webapps\\guimei\\";

        // 2.2 获取上传的文件名
        String filename = file.getOriginalFilename();
        System.out.println(filename);
        // 2.3 如果图片名称是中文，需要转换
        try {
            filename = new String(filename.getBytes("iso-8859-1"), "utf-8");
            System.out.println("转换后的中文图片名称：" + filename);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 2.4 在上传之前我们要考虑文件名的唯一性
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 拼接后的文件名
        String uploadFileName = uuid + filename;
        System.out.println("上传的文件名：" + uploadFileName);

        // 2.5 创建上传的文件对象
        File uploadFile = new File(uploadPath, uploadFileName);

        // 2.6 上传
        try {
            file.transferTo(uploadFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 2.7 保存到数据库的路径
        userImagePath = "http://localhost:8083/guimei/" + uploadFileName;

        JsonResult jsonResult = JsonResult.ok();
        jsonResult.setData(userImagePath);

        return jsonResult;
    }

    /**
     * 3、添加
     */
    @RequestMapping("addUser")
    public void addUser(User user, HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println(user);
        // 设置上传路径
        if (user != null) {
            user.setUserImage(userImagePath);
            // 添加
            userService.addUser(user);
            // 跳转页面
            response.sendRedirect(request.getContextPath() + "/index.html");

        } else {
            throw new RuntimeException("user为空");
        }
    }

    /**
     * 4、修改
     */
    @RequestMapping("updateUser")
    public String updateUser(User user) {
        if (user != null) {
            userService.updateUser(user);
            return "success";
        } else {
            throw new RuntimeException("user为空");
        }
    }

    /**
     * 5、删除用户
     */
    @RequestMapping("deleteById")
    public String deleteById(Integer id) {
        userService.deleteById(id);
        return "success";
    }

    /**
     * 6、批量删除用户
     */
    @RequestMapping("deleteByIds")
    public String deleteByIds(Integer[] ids) {
        System.out.println("deleteByIds: " + Arrays.toString(ids));
        userService.deleteByIds(ids);
        return "success";
    }

    /**
     * 7、导出Excel
     */
    @RequestMapping("findByIds")
    public void findByIds(Integer[] ids, HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println(Arrays.toString(ids));

        // 7.1 判断ids不为空，确保导出数据存在数值
        if (ids != null && ids.length > 0) {
            List<User> userList = userService.findByIds(ids);// 返回7.2 User List集合
            System.out.println("userList: " + userList);

            // 7.3 第一种方式： 写入Excel System.currentTimeMillis() : 系统当前时间(选中对象的当前毫秒值)
//            String fileName = "D:/" + System.currentTimeMillis() + ".xlsx";
//            EasyExcel.write(fileName,User.class).sheet("模板").doWrite(userList);

            // 7.4 第二种方式: 以下载的方式导出Excel
            String fileName = System.currentTimeMillis() + ".xlsx";
            // 7.5 设置响应头，Content-Disposition: attachment; filename=aaa.zip --告诉浏览器以下载方式打开资源（文件下载）
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            // 7.6 获取流对象    = 响应.获取输出流
            ServletOutputStream outputStream = response.getOutputStream();
            // 7.7 写入Excel
            EasyExcel.write(outputStream, User.class).sheet("用户列表").doWrite(userList);
        } else {
            throw new RuntimeException("ids为空");
        }
    }

    /**
     * 8、导入Excel
     */
    @RequestMapping("readExcel")
    public JsonResult readExcel(MultipartFile file) {
        if (file != null) {
            userService.readExcel(file);
            return JsonResult.ok();
        }
        throw new RuntimeException("上传文件异常");
    }

    /**
     * 9、男女用户比例(柱状图)
     */
    @RequestMapping("getUserGenderDto")
    public UserGenderDto getUserGenderDto() {
        // 先去数据库查询男女人数(用户性别 Dto 列表)
        List<UserGenderDto> userGenderDtoList = userService.findGender();
        System.out.println(userGenderDtoList);

        // 存储： 男， 女
        String [] genders = new String[userGenderDtoList.size()];
        // 存储：7， 5
        Integer [] genderNums = new Integer[userGenderDtoList.size()];
        
        // 遍历并赋值 (用户性别 Dto 列表.size())
        for (int i = 0; i < userGenderDtoList.size(); i++) {
            genders[i] = userGenderDtoList.get(i).getGender();// 女
            genderNums[i] = userGenderDtoList.get(i).getGenderNum();// 5
        }

        // 赋值 用户性别 Dto
        UserGenderDto userGenderDto = new UserGenderDto();
        userGenderDto.setGendersDate(genders);

        userGenderDto.setName("性别");
        userGenderDto.setType("bar");
        userGenderDto.setData(genderNums);

        return userGenderDto;
    }

    /**
     * 10、获取用户位置以及人数
     */
    @RequestMapping("getUserAddressDto")
    public List<UserAddressDto> getUserAddressDto() {

        // 查询数据
        List<UserAddress> userAddressList = userService.findAddress();

        // 赋值
        List<UserAddressDto> userAddressDtoList = new ArrayList<>();

        // 遍历
        for (int i = 0; i < userAddressList.size(); i++) {
            UserAddressDto userAddressDto = new UserAddressDto();
            // 赋值
            userAddressDto.setName(userAddressList.get(i).getAddress());
            userAddressDto.setValue(BigDecimal.valueOf(userAddressList.get(i).getAddressNum()));
            // 添加到集合
            userAddressDtoList.add(userAddressDto);
        }
        return userAddressDtoList;
    }
}
